package tools

import (
	"crypto/hmac"
	MD5 "crypto/md5"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"io"
	"math/rand"
	"regexp"
	"strconv"
	"strings"
	"time"
)

func init() {
	rand.Seed(time.Now().UnixMilli())
}

/**
 * @Description: 检测两组用空格分隔的字符串是否有相同的单词
 * @receiver this
 * @param findIn 原始字符串
 * @param find 要搜索的字符串
 * @return bool
 */
func HasSameWord(findIn string, find string) bool {
	var findInArr, findArr []string
	findInArr = strings.Fields(findIn)
	findArr = strings.Fields(find)
	for _, itemIn := range findInArr {
		for _, item := range findArr {
			if item == itemIn {
				return true
			}
		}
	}
	return false
}
func Ucfirst(str string) string {
	upperCase := ""
	if len(str) == 0 {
		return str
	} else {
		upperCase = strings.ToUpper(str[:1]) + str[1:]
	}
	return upperCase
}
func UcfirstArr(in []string) (out []string) {
	out = make([]string, 0)
	for _, str := range in {
		out = append(out, Ucfirst(str))
	}
	return
}

func Lcfirst(str string) string {
	var upperStr string
	vv := []rune(str) // 后文有介绍
	for i := 0; i < len(vv); i++ {
		if i == 0 {
			if vv[i] >= 65 && vv[i] <= 121 { // 后文有介绍
				vv[i] += 32 // string的码表相差32位
				upperStr += string(vv[i])
			} else {
				//fmt.Println("Not begins with lowercase letter,")
				return str
			}
		} else {
			upperStr += string(vv[i])
		}
	}
	return upperStr
}

func LcfirstArr(in []string) (out []string) {
	out = make([]string, 0)
	for _, str := range in {
		out = append(out, Lcfirst(str))
	}
	return
}
func Md5(str string) string {
	data := []byte(str)
	return fmt.Sprintf("%x", MD5.Sum(data))
}

func Int64ToInt(int64 int64) int {
	strInt64 := strconv.FormatInt(int64, 10)
	int_16, _ := strconv.Atoi(strInt64)
	return int_16
}

func Float64ToInt(int64 float64) int {
	strInt64 := strconv.FormatFloat(int64, 'e', 10, 64)
	int_16, _ := strconv.Atoi(strInt64)
	return int_16
}

func SHA256(message []byte) string {
	bytes2 := sha256.Sum256(message)           //计算哈希值，返回一个长度为32的数组
	hashcode2 := hex.EncodeToString(bytes2[:]) //将数组转换成切片，转换成16进制，返回字符串
	return hashcode2
}
func HmacHs256(message string, secret string) string {
	h := hmac.New(sha256.New, []byte(secret))
	io.WriteString(h, message)
	return fmt.Sprintf("%x", h.Sum(nil))
}
func CreateOrderSn(randLen int, prefix string, suffix string) string {
	base := prefix + GetDateYMDHIS("", "", "") + CreateRand(randLen) + suffix
	return base
}

func CreateRand(randLen int) string {
	//rand.Seed(time.Now().UnixNano())
	base := strconv.Itoa(Pow(10, randLen-1) + rand.Intn(8*Pow(10, randLen-1)+Pow(10, randLen-2)-1))
	return base
}
func CreatRandomInt(min, max int) int {
	return min + rand.Intn(max-min)
}
func CreateRandString(len int) string {
	bytes := make([]byte, len)
	for i := 0; i < len; i++ {
		bytes[i] = byte(CreatRandomInt(65, 90))
	}
	return string(bytes)
}
func StringArrayUnique(orgSlice []string) {
	var tmpMap = make(map[string]bool)
	for _, item := range orgSlice {
		tmpMap[item] = true
	}
	var backSlice []string
	for item, _ := range tmpMap {
		backSlice = append(backSlice, item)
	}
	orgSlice = backSlice
}

func MatchAll(str string, pattern string) [][]string {
	reg := regexp.MustCompile(pattern)
	if reg == nil {
		return nil
	}
	return reg.FindAllStringSubmatch(str, -1)
}

func ReplaceAll(str string, pattern string, replace string) string {
	reg := regexp.MustCompile(pattern)
	if reg == nil {
		return ""
	}
	return reg.ReplaceAllString(str, replace)
}

func Match(str string, pattern string) bool {
	reg := regexp.MustCompile(pattern)
	if reg == nil {
		return false
	}
	return reg.Match([]byte(str))
}

func SnakeString(s string) string {
	data := make([]byte, 0, len(s)*2)
	j := false
	num := len(s)
	for i := 0; i < num; i++ {
		d := s[i]
		// or通过ASCII码进行大小写的转化
		// 65-90（A-Z），97-122（a-z）
		//判断如果字母为大写的A-Z就在前面拼接一个_
		if i > 0 && d >= 'A' && d <= 'Z' && j {
			data = append(data, '_')
		}
		if d != '_' {
			j = true
		}
		data = append(data, d)
	}
	//ToLower把大写字母统一转小写
	return strings.ToLower(string(data[:]))
}

func SnakeStrings(in []string) (out []string) {
	out = make([]string, 0)
	for _, i := range in {
		out = append(out, SnakeString(i))
	}
	return
}

func CamelString(s string) string {
	data := make([]byte, 0, len(s))
	j := false
	k := false
	num := len(s) - 1
	for i := 0; i <= num; i++ {
		d := s[i]
		if k == false && d >= 'A' && d <= 'Z' {
			k = true
		}
		if d >= 'a' && d <= 'z' && (j || k == false) {
			d = d - 32
			j = false
			k = true
		}
		if k && d == '_' && num > i && s[i+1] >= 'a' && s[i+1] <= 'z' {
			j = true
			continue
		}
		data = append(data, d)
	}
	return string(data[:])
}

func CamelStrings(in []string) (out []string) {
	out = make([]string, 0)
	for _, i := range in {
		out = append(out, CamelString(i))
	}
	return
}
func Replaces(toReplace string, froms []string, tos []string) (rst string) {
	makeOldNews := func(from []string, to []string) []string {
		wanted := make([]string, 2*len(from))
		for i, s := range from {
			wanted = append(wanted, s, to[i])
		}
		return wanted
	}
	replacer := strings.NewReplacer(makeOldNews(froms, tos)...)
	rst = replacer.Replace(toReplace)
	return
}
func ContainsString(src []string, dest string) bool {
	for _, item := range src {
		if item == dest {
			return true
		}
	}
	return false
}

// DifferenceStrings 取前者src与后者dest两个字符串列表的差集
func DifferenceStrings(src []string, dest []string) []string {
	res := make([]string, 0)
	for _, item := range src {
		if !ContainsString(dest, item) {
			res = append(res, item)
		}
	}
	return res
}

// IntersectionStrings 取两个字符串列表的交集
func IntersectionStrings(src []string, dest []string) []string {
	res := make([]string, 0)
	for _, item := range src {
		if ContainsString(dest, item) {
			res = append(res, item)
		}
	}
	return res
}

// UnionString 取两个字符串列表的并集
func UnionStrings(src []string, dest []string) []string {
	res := make([]string, 0)
	res = append(res, src...)
	for _, item := range dest {
		if !ContainsString(res, item) {
			res = append(res, item)
		}
	}
	return res
}
